package bdhub.littletail.lib.ui.widget;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.style.ReplacementSpan;

import java.lang.ref.WeakReference;

public class DrawableSpan extends ReplacementSpan {
	private static final String TAG = "DrawableSpan";
	
	/**
	 * A constant indicating that the bottom of this span should be aligned with
	 * the bottom of the surrounding text, i.e., at the same level as the lowest
	 * descender in the text.
	 */
	public static final int ALIGN_BOTTOM = 0;

	/**
	 * A constant indicating that the bottom of this span should be aligned with
	 * the baseline of the surrounding text.
	 */
	public static final int ALIGN_BASELINE = 1;
	
	/**
	 * 居中对齐
	 */
	public static final int ALIGN_CENTER = 2;

	protected final Drawable mDrawable;
	protected final int mVerticalAlign;

	/**
	 * @param mVerticalAlign
	 *            one of {@link #ALIGN_BOTTOM} or {@link #ALIGN_BASELINE}.
	 */
	public DrawableSpan(Drawable drawable, int valign) {
		mDrawable = drawable;
		mVerticalAlign = valign;
	}

	/**
	 * Returns the vertical alignment of this span, one of {@link #ALIGN_BOTTOM}
	 * or {@link #ALIGN_BASELINE}.
	 */
	public int getValign() {
		return mVerticalAlign;
	}

	public Drawable getDrawable() {
		return mDrawable;
	}

	@Override
	public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
		Rect rect = mDrawable.getBounds();

		if (fm != null) {
			fm.ascent = -rect.bottom;
			fm.descent = 0;

			fm.top = fm.ascent;
			fm.bottom = 0;
		}

		return rect.right;
	}

	/**
	 * y is baseline_y
	 * 
	 */
	@Override
	public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y,
					 int bottom, Paint paint) {
		Drawable d = getCachedDrawable();
		canvas.save();

		int transY;
		if (ALIGN_BOTTOM == mVerticalAlign) {
			transY = bottom;
			transY -= d.getBounds().bottom;
		} else if(ALIGN_BASELINE == mVerticalAlign){ 
			transY = y;
			transY -= d.getBounds().bottom;
		} else {
			transY = top ;
			transY += ((bottom - top) - d.getBounds().height())/2;
		}
		
//		Log.d(TAG,String.format("x=%d, y=%d, top=%d, bottom=%d," +
//				" descent=%d, d_bottom=%d", (int)x, y, top, bottom,
//				paint.getFontMetricsInt().descent, d.getBounds().bottom));

		canvas.translate(x, transY);
		d.draw(canvas);
		canvas.restore();
	}

	private Drawable getCachedDrawable() {
        WeakReference<Drawable> wr = mDrawableRef;
        Drawable d = null;

        if (wr != null)
            d = wr.get();

        if (d == null) {
            d = getDrawable();
            mDrawableRef = new WeakReference<Drawable>(d);
        }

        return d;
    }

    private WeakReference<Drawable> mDrawableRef;
}